package com.example.demo.utils;

/**
 * 响应信息主体，用于封装RESTful API的响应数据。
 *
 * @author zhongshunhao
 * @date 2024/8/12 11:06
 **/
public class Result<T> {
    /**
     * 操作成功
     */
    public static final int SUCCESS = 200;

    /**
     * 对象创建成功
     */
    public static final int CREATED = 201;

    /**
     * 请求已经被接受
     */
    public static final int ACCEPTED = 202;

    /**
     * 操作已经执行成功，但是没有返回数据
     */
    public static final int NO_CONTENT = 204;

    /**
     * 资源已被移除
     */
    public static final int MOVED_PERM = 301;

    /**
     * 重定向
     */
    public static final int SEE_OTHER = 303;

    /**
     * 资源没有被修改
     */
    public static final int NOT_MODIFIED = 304;

    /**
     * 参数列表错误（缺少，格式不匹配）
     */
    public static final int BAD_REQUEST = 400;

    /**
     * 未授权
     */
    public static final int UNAUTHORIZED = 401;

    /**
     * 访问受限，授权过期
     */
    public static final int FORBIDDEN = 403;

    /**
     * 资源，服务未找到
     */
    public static final int NOT_FOUND = 404;

    /**
     * 不允许的http方法
     */
    public static final int BAD_METHOD = 405;

    /**
     * 资源冲突，或者资源被锁
     */
    public static final int CONFLICT = 409;

    /**
     * 不支持的数据，媒体类型
     */
    public static final int UNSUPPORTED_TYPE = 415;

    /**
     * 系统内部错误
     */
    public static final int ERROR = 500;

    /**
     * 接口未实现
     */
    public static final int NOT_IMPLEMENTED = 501;

    /**
     * 系统警告消息
     */
    public static final int WARN = 601;


    // 响应状态码，用于表示请求是否成功
    private int code;

    // 响应消息，用于提供操作结果的描述
    private String msg;

    // 泛型数据，用于存储操作结果的具体数据
    private T data;

    /**
     * 私有构造函数，防止外部直接实例化
     */
    private Result() {
    }

    // 静态工厂方法，创建一个操作成功的响应对象，无数据和默认成功消息
    public static <T> Result<T> ok() {
        return restResult(null, SUCCESS, "操作成功");
    }

    // 静态工厂方法，创建一个操作成功的响应对象，包含数据和默认成功消息
    public static <T> Result<T> ok(T data) {
        return restResult(data, SUCCESS, "操作成功");
    }

    // 静态工厂方法，创建一个操作成功的响应对象，包含数据和自定义消息
    public static <T> Result<T> ok(T data, String msg) {
        return restResult(data, SUCCESS, msg);
    }

    // 静态工厂方法，创建一个操作失败的响应对象，无数据和默认失败消息
    public static <T> Result<T> fail() {
        return restResult(null, ERROR, "操作失败");
    }

    // 静态工厂方法，创建一个操作失败的响应对象，包含自定义失败消息
    public static <T> Result<T> fail(String msg) {
        return restResult(null, ERROR, msg);
    }

    // 静态工厂方法，创建一个操作失败的响应对象，包含数据和默认失败消息
    public static <T> Result<T> fail(T data) {
        return restResult(data, ERROR, "操作失败");
    }

    // 静态工厂方法，创建一个操作失败的响应对象，包含数据和自定义消息
    public static <T> Result<T> fail(T data, String msg) {
        return restResult(data, ERROR, msg);
    }

    // 静态工厂方法，创建一个自定义状态码和消息的响应对象
    public static <T> Result<T> fail(int code, String msg) {
        return restResult(null, code, msg);
    }

    // 私有静态工厂方法，用于实际创建Result对象
    private static <T> Result<T> restResult(T data, int code, String msg) {
        Result<T> apiResult = new Result<T>();
        apiResult.setCode(code);
        apiResult.setData(data);
        apiResult.setMsg(msg);
        return apiResult;
    }

    // getter和setter方法
    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

    // 辅助方法，用于检查响应对象是否表示错误
    public static <T> boolean isError(Result<T> ret) {
        return ret == null || ret.getCode() != SUCCESS;
    }

    // 辅助方法，用于检查响应对象是否表示成功
    public static <T> boolean isSuccess(Result<T> ret) {
        return ret != null && ret.getCode() == SUCCESS;
    }
}